package com.bes.aiProject.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.bes.aiProject.config.MyUtils;
import com.bes.aiProject.entry.SxAAbnormalResult;
import com.bes.aiProject.entry.SxAAnalyzeResultTemp;
import com.bes.aiProject.entry.SxMBusinessProcessScore;
import com.bes.aiProject.entry.SxMMetricConf;
import com.bes.aiProject.mapper.SxAAnalyzeResultTempMapper;
import com.bes.aiProject.mapper.SxMBusinessProcessScoreMapper;
import com.bes.aiProject.mapper.SxMMetricConfMapper;
import com.bes.aiProject.service.AIService;
import com.bes.aiProject.service.ModelPredictService;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ModelPredictServiceImpl implements ModelPredictService {
    Gson gson = new Gson();
    @Value("${ai.anomaly.url}")
    String anomalyAIUrl;
    @Value("${ai.train.url}")
    String trainAIUrl;
    @Value("${ai.train.path}")
    String trainAIPath;
    @Value("${ai.predict.url}")
    String predictAIUrl;

    @Autowired
    RestTemplate restTemplate;
    @Autowired
    SxMBusinessProcessScoreMapper processScoreMapper;
    @Autowired
    SxMMetricConfMapper metricConfMapper;
    @Autowired
    AIService aiService;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    @Autowired
    SxAAnalyzeResultTempMapper analyzeResultTempMapper;

    @Override
    public void ModelPredict() {

    }

    @Override
    public void ModelPredictMetric(List<SxAAbnormalResult> results, List<String> conditionList, SxAAbnormalResult conditionObject) {
        LocalDateTime currentTime = LocalDateTime.now();
        Type type = new TypeToken<Map<String, Object>>() {
        }.getType();
        Map<String, Object> objectMap = gson.fromJson(gson.toJson(results.get(0)), type);
        StringBuilder modelIdBuilder = new StringBuilder();
        StringBuilder modelNameBuilder = new StringBuilder();
        //循环到最后的一个节点id,用于回填权重
        String leafCode = "";
        for (String s : conditionList) {
            List<String> keys = MyUtils.ConditionMap.get(s);
            modelIdBuilder.append(objectMap.get(keys.get(0)).toString()).append("_");
            modelNameBuilder.append(objectMap.get(keys.get(1)).toString()).append("_");
            leafCode = objectMap.get(keys.get(0)).toString();
        }
        modelIdBuilder.setLength(modelIdBuilder.length() - 1);
        modelNameBuilder.setLength(modelNameBuilder.length() - 1);
        //获取时间+指标分数（每一个时间点，一个指标只有一个分数）
        Map<LocalDateTime, List<SxAAbnormalResult>> collect = results.stream().collect(Collectors.groupingBy(SxAAbnormalResult::getAbnormalTime));
        //组装训练数据
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("modelId", modelIdBuilder.toString());
        requestMap.put("modelName", modelNameBuilder.toString());
        requestMap.put("trainPath", trainAIPath);
        requestMap.put("leafCode", leafCode);
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, String> features = new HashMap<>();
        for (LocalDateTime keyTime : collect.keySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("metricTime", keyTime.format(formatter));
            for (SxAAbnormalResult abnormalResult : collect.get(keyTime)) {
                item.put(abnormalResult.getMetricCode(), abnormalResult.getScore());
                features.put(abnormalResult.getMetricCode(), abnormalResult.getMetricName());
            }
            data.add(item);
        }
        requestMap.put("data", data);
        requestMap.put("features", features);
        //调用AI
        HashMap responseMap = aiService.callPredictAI(requestMap);
        if (CollectionUtils.isEmpty(responseMap)) {
            log.error("异常检测调用AI接口报错,任务终止！");
            return;
        }
        HashMap responseData = (HashMap) responseMap.get("data");
        if (0 == (int) responseMap.get("code")) {
            log.info("异常检测调用AI接口成功");
            Map<String, Double> importanceMap = (Map<String, Double>) responseData.get("featureImportance");
            List<Map<String, Object>> scoreList = (List<Map<String, Object>>) responseData.get("score");
            //插入预测结果到临时分析表

            log.info("异常检测结果保存成功!");
        } else {
            log.info("异常检测调用AI接口失败！");
        }
    }
}
